import org.apache.ignite.cache.store.CacheStore;
import org.apache.ignite.lang.IgniteBiInClosure;

import javax.cache.Cache;
import javax.cache.integration.CacheLoaderException;
import javax.cache.integration.CacheWriterException;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class DBCacheStore<K, V> implements CacheStore<Object, V>, Serializable {

    private Class entityClass;
    public DBCacheStore(Class entityClass) {
        this.entityClass = entityClass;
    }

    @Override
    public void loadCache(IgniteBiInClosure clo,  Object... objects) throws CacheLoaderException {

        System.out.println(String.format("Loading %s cache from store...", entityClass.getSimpleName()));

        int start = 0;
        int limit = 5000;

        while(true) {
            List list = DB.find(entityClass, "1=1 limit ?,?", start, limit);

            if (list.size() == 0) {
                break;
            }
            for (Object entity: list) {
                try {
                    clo.apply(entity.getClass().getField("id").get(entity), entity);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            System.out.println(String.format("%s %s loaded.", start + list.size(), entityClass.getSimpleName()));
            start += limit;
        }
    }

    /**
     * @param b
     * @deprecated
     */
    @Override
    public void sessionEnd(boolean b) throws CacheWriterException {

    }

    // This method is called whenever IgniteCache.get() method is called.

    @Override

    public V load(Object key) throws CacheLoaderException {
        return null;

    }

    @Override
    public Map loadAll(Iterable iterable) throws CacheLoaderException {
        return null;
    }

    @Override
    public void write(Cache.Entry entry) throws CacheWriterException {
        try {
            DB.withTransaction(new Execute() {
                @Override
                public void call() throws Exception {
                    save(entry.getValue());
                }
            });
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void writeAll(Collection<Cache.Entry<?, ? extends V>> collection) throws CacheWriterException {

    }

    @Override
    public void delete(Object o) throws CacheWriterException {
    }

    @Override
    public void deleteAll(Collection collection) throws CacheWriterException {

    }
}
